import java.time.*;
import java.util.*;
import java.util.stream.Collectors;
import java.io.*;
class CinemaSystem implements Serializable {
    private List<User> users;
    private List<Movie> movies;
    private List<Session> sessions;
    private List<Ticket> tickets;
    private Logger logger;
    private User currentUser;

    public CinemaSystem() {
        users = new ArrayList<>();
        movies = new ArrayList<>();
        sessions = new ArrayList<>();
        tickets = new ArrayList<>();
        logger = new Logger();
        initializeSystem();
    }

    private void initializeSystem() {
        users.add(new Administractor("ADM001", "admin", "ynuinfo#777", "13800138000"));

        movies.add(new Movie("流浪地球", "郭帆", "吴京, 屈楚萧, 李光洁",
                "太阳即将毁灭，人类在地球表面建造出巨大的推进器，寻找新家园。然而宇宙之路危机四伏，为了拯救地球，流浪地球时代的年轻人挺身而出，展开争分夺秒的生死之战。",
                125, 9.0f));

        movies.add(new Movie("哪吒之魔童降世", "饺子", "吕艳婷, 囧森瑟夫, 瀚墨",
                "天地灵气孕育出一颗能量巨大的混元珠，元始天尊将混元珠提炼成灵珠和魔丸，灵珠投胎为人，助周伐纣时可堪大用；而魔丸则会诞出魔王，为祸人间。",
                110, 9.6f));

        movies.add(new Movie("复仇者联盟4：终局之战", "安东尼·罗素", "小罗伯特·唐尼, 克里斯·埃文斯, 马克·鲁法洛",
                "在灭霸消灭宇宙一半的生灵并重创复仇者联盟之后，剩余的英雄被迫背水一战，为22部漫威电影写下传奇终章。",
                181, 9.2f));
        LocalDateTime now = LocalDateTime.now();
        sessions.add(new Session("S001", movies.get(0), ScreeningRoom.GOLD, now.plusHours(2), 45.0f));
        sessions.add(new Session("S002", movies.get(1), ScreeningRoom.SILVER, now.plusHours(4), 40.0f));
        sessions.add(new Session("S003", movies.get(2), ScreeningRoom.DIAMOND, now.plusHours(6), 55.0f));
    }

    public boolean login(String username, String password) {
        for (User user : users) {
            if (user.login(username, password)) {
                currentUser = user;
                System.out.println("登录成功! 欢迎您, " + user.getUsername());
                return true;
            }
            System.out.println("用户名或密码错误!");
        }
        return false;
    }

    public void logout() {
        if (currentUser != null) {
            System.out.println("再见, " + currentUser.getUsername() + "!");
            currentUser = null;
        }
    }

    public void showMainMenu() {
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("\n===== 万东影院管理系统 =====");
            System.out.println("1. 登录");
            System.out.println("2. 退出系统");
            System.out.print("请选择操作: ");

            int choice = scanner.nextInt();
            scanner.nextLine();

            switch (choice) {
                case 1:
                    System.out.print("用户名: ");
                    String username = scanner.nextLine();
                    System.out.print("密码: ");
                    String password = scanner.nextLine();

                    if (login(username, password)) {
                        currentUser.showMenu(logger, this);
                    }
                    break;
                case 2:
                    System.out.println("感谢使用万东影院管理系统!");
                    return;
                default:
                    System.out.println("无效选择!");
            }
        }
    }
    public void addUserByAdmin(Logger logger, Administractor admin) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("输入用户ID: ");
        String userId = scanner.nextLine();

        System.out.print("输入用户名: ");
        String username = scanner.nextLine();

        System.out.print("输入手机号: ");
        String phone = scanner.nextLine();

        System.out.println("选择用户类型:");
        System.out.println("1. 管理员");
        System.out.println("2. 经理");
        System.out.println("3. 前台");
        System.out.print("请选择: ");
        int typeChoice = scanner.nextInt();
        scanner.nextLine();

        String userType = "";
        switch (typeChoice) {
            case 1: userType = "管理员"; break;
            case 2: userType = "经理"; break;
            case 3: userType = "前台"; break;
            default:
                System.out.println("无效选择!");
                return;
        }

        if (users.stream().anyMatch(u -> u.getUserId().equals(userId))) {
            System.out.println("用户ID已存在!");
            return;
        }
        if (users.stream().anyMatch(u -> u.getUsername().equals(username))) {
            System.out.println("用户名已存在!");
            return;
        }
        if (users.stream().anyMatch(u -> u.getPhone().equals(phone))) {
            System.out.println("手机号已存在!");
            return;
        }

        User newUser;
        switch (userType) {
            case "管理员":
                newUser = new Administractor(userId, username, "123456", phone);
                break;
            case "经理":
                newUser = new Manager(userId, username, "123456", phone);
                break;
            case "前台":
                newUser = new FrontDesk(userId, username, "123456", phone);
                break;
            default:
                System.out.println("无效用户类型!");
                return;
        }

        users.add(newUser);
        System.out.println("用户添加成功! 初始密码: 123456");
        logger.logAction("添加用户: " + username, admin.getUsername());
    }
    public void resetUserPassword(String username, Logger logger, Administractor admin) {
        Optional<User> userOpt = users.stream().filter(u -> u.getUsername().equals(username)).findFirst();

        if (userOpt.isPresent()) {
            User user = userOpt.get();
            if (user.getUserType().equals("管理员") && user.getUsername().equals("admin")) {
                System.out.println("不能重置admin密码!");
                return;
            }

            user.setPassword("123456");
            System.out.println("密码已重置为123456");
            logger.logAction("重置用户密码: " + username, admin.getUsername());
        } else {
            System.out.println("用户不存在!");
        }
    }

    public void deleteUser(String username, Logger logger,  Administractor admin) {
        Optional<User> userOpt = users.stream().filter(u -> u.getUsername().equals(username)).findFirst();

        if (userOpt.isPresent()) {
            User user = userOpt.get();

            if (user.getUsername().equals("admin")) {
                System.out.println("不能删除admin账户!");
                return;
            }

            users.remove(user);
            System.out.println("用户已删除");
            logger.logAction("删除用户: " + username, admin.getUsername());
        } else {
            System.out.println("用户不存在!");
        }
    }

    public void listAllUsers() {
        System.out.println("\n===== 用户列表 =====");
        users.forEach(u -> System.out.printf("ID: %s, 用户名: %s, 类型: %s, 手机: %s, 注册时间: %s%n", u.getUserId(), u.getUsername(), u.getUserType(), u.getPhone(), u.getRegisterTime()));
    }
    public void queryUser(String query) {
        List<User> result = users.stream().filter(u -> u.getUserId().equals(query) || u.getUsername().equals(query)).collect(Collectors.toList());

        if (result.isEmpty()) {
            System.out.println("未找到匹配用户");
        } else {
            System.out.println("\n===== 查询结果 =====");
            result.forEach(u -> System.out.printf("ID: %s, 用户名: %s, 类型: %s, 手机: %s%n", u.getUserId(), u.getUsername(), u.getUserType(), u.getPhone()));
        }
    }

    public void modifyUserInfo(String username, Logger logger, Administractor admin) {
        Optional<User> userOpt = users.stream().filter(u -> u.getUsername().equals(username)).findFirst();

        if (userOpt.isPresent()) {
            User user = userOpt.get();

            if (user.getUserType().equals("管理员") && user.getUsername().equals("admin")) {
                System.out.println("不能修改admin账户信息!");
                return;
            }

            Scanner scanner = new Scanner(System.in);

            System.out.println("当前信息:");
            System.out.printf("用户类型: %s, 手机号: %s%n", user.getUserType(), user.getPhone());

            System.out.println("1. 修改用户类型");
            System.out.println("2. 修改手机号");
            System.out.print("请选择: ");
            int choice = scanner.nextInt();
            scanner.nextLine();

            switch (choice) {
                case 1:
                    System.out.println("选择新用户类型:");
                    System.out.println("1. 经理");
                    System.out.println("2. 前台");
                    System.out.print("请选择: ");
                    int typeChoice = scanner.nextInt();
                    scanner.nextLine();

                    if (typeChoice == 1) {
                        user.setUserType("经理");
                    } else if (typeChoice == 2) {
                        user.setUserType("前台");
                    } else {
                        System.out.println("无效选择!");
                    }
                    break;
                case 2:
                    System.out.print("输入新手机号: ");
                    String newPhone = scanner.nextLine();

                    if (users.stream().anyMatch(u -> u.getPhone().equals(newPhone) && !u.getUsername().equals(username))) {
                        System.out.println("手机号已存在!");
                        return;
                    }

                    user.setPhone(newPhone);
                    break;
                default:
                    System.out.println("无效选择!");
                    return;
            }

            System.out.println("信息修改成功!");
            logger.logAction("修改用户信息: " + username, admin.getUsername());
        } else {
            System.out.println("用户不存在!");
        }
    }

    public void addMovie(Logger logger, Manager manager) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("输入片名: ");
        String title = scanner.nextLine();

        System.out.print("输入导演: ");
        String director = scanner.nextLine();

        System.out.print("输入主演: ");
        String actors = scanner.nextLine();

        System.out.print("输入剧情简介: ");
        String description = scanner.nextLine();

        System.out.print("输入时长(分钟): ");
        int duration = scanner.nextInt();

        System.out.print("输入评分(0-10): ");
        float rating = scanner.nextFloat();
        scanner.nextLine();

        if (movies.stream().anyMatch(m -> m.getTitle().equals(title))) {
            System.out.println("影片已存在!");
            return;
        }

        Movie newMovie = new Movie(title, director, actors, description, duration, rating);
        movies.add(newMovie);
        System.out.println("影片添加成功!");
        logger.logAction("添加影片: " + title, manager.getUsername());
    }

    public void modifyMovie(String title, Logger logger, Manager manager) {
        Optional<Movie> movieOpt = movies.stream().filter(m -> m.getTitle().equals(title)).findFirst();

        if (movieOpt.isPresent()) {
            Movie movie = movieOpt.get();
            Scanner scanner = new Scanner(System.in);

            System.out.println("当前信息:");
            System.out.println(movie);

            System.out.println("1. 修改导演");
            System.out.println("2. 修改主演");
            System.out.println("3. 修改剧情简介");
            System.out.println("4. 修改时长");
            System.out.println("5. 修改评分");
            System.out.print("请选择: ");
            int choice = scanner.nextInt();
            scanner.nextLine();

            switch (choice) {
                case 1:
                    System.out.print("输入新导演: ");
                    movie.setDirector(scanner.nextLine());
                    break;
                case 2:
                    System.out.print("输入新主演: ");
                    movie.setActors(scanner.nextLine());
                    break;
                case 3:
                    System.out.print("输入新剧情简介: ");
                    movie.setDescription(scanner.nextLine());
                    break;
                case 4:
                    System.out.print("输入新时长: ");
                    movie.setDuration(scanner.nextInt());
                    scanner.nextLine();
                    break;
                case 5:
                    System.out.print("输入新评分: ");
                    movie.setRating(scanner.nextFloat());
                    scanner.nextLine();
                    break;
                default:
                    System.out.println("无效选择!");
                    return;
            }

            System.out.println("影片信息修改成功!");
            logger.logAction("修改影片信息: " + title, manager.getUsername());
        } else {
            System.out.println("影片不存在!");
        }
    }
    public void deleteMovie(String title, Logger logger, Manager manager) {
        Optional<Movie> movieOpt = movies.stream().filter(m -> m.getTitle().equals(title)).findFirst();

        if (movieOpt.isPresent()) {
            Movie movie = movieOpt.get();

            boolean hasSessions = sessions.stream().anyMatch(s -> s.getMovie().getTitle().equals(title));

            if (hasSessions) {
                System.out.println("该影片有排片，不能删除!");
                return;
            }

            movies.remove(movie);
            System.out.println("影片删除成功!");
            logger.logAction("删除影片: " + title, manager.getUsername());
        } else {
            System.out.println("影片不存在!");
        }
    }

    public void queryMovies(String query) {
        List<Movie> result = movies.stream().filter(m -> m.getTitle().contains(query) || m.getDirector().contains(query) || m.getActors().contains(query)).collect(Collectors.toList());

        if (result.isEmpty()) {
            System.out.println("未找到匹配影片");
        } else {
            System.out.println("\n===== 查询结果 =====");
            result.forEach(System.out::println);
        }
    }

    public void listAllMovies() {
        System.out.println("\n===== 影片列表 =====");
        movies.forEach(System.out::println);
    }

    public void addSession(Logger logger, Manager manager) {
        if (movies.isEmpty()) {
            System.out.println("请先添加影片!");
            return;
        }

        Scanner scanner = new Scanner(System.in);
        System.out.println("选择影片:");
        for (int i = 0; i < movies.size(); i++) {
            System.out.printf("%d. %s%n", i + 1, movies.get(i).getTitle());
        }
        System.out.print("请选择: ");
        int movieIndex = scanner.nextInt() - 1;
        scanner.nextLine();

        if (movieIndex < 0 || movieIndex >= movies.size()) {
            System.out.println("无效选择!");
            return;
        }
        Movie movie = movies.get(movieIndex);

        System.out.println("选择影厅:");
        ScreeningRoom[] rooms = ScreeningRoom.values();
        for (int i = 0; i < rooms.length; i++) {
            System.out.printf("%d. %s (座位: %d)%n", i + 1, rooms[i].getName(), rooms[i].getTotalSeats());
        }
        System.out.print("请选择: ");
        int roomIndex = scanner.nextInt() - 1;
        scanner.nextLine();

        if (roomIndex < 0 || roomIndex >= rooms.length) {
            System.out.println("无效选择!");
            return;
        }
        ScreeningRoom room = rooms[roomIndex];

        System.out.print("输入场次时间 (格式: yyyy-MM-dd HH:mm): ");
        String timeStr = scanner.nextLine();
        LocalDateTime time = LocalDateTime.parse(timeStr, java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));

        if (time.isBefore(LocalDateTime.now()) ){
            System.out.println("场次时间不能在当前时间之前!");
            return;
        }
        if (time.isAfter(LocalDateTime.now().plusDays(7))) {
            System.out.println("只能安排未来一周内的场次!");
            return;
        }

        System.out.print("输入票价: ");
        float price = scanner.nextFloat();
        scanner.nextLine();

        String sessionId = "S" + String.format("%03d", sessions.size() + 1);

        Session newSession = new Session(sessionId, movie, room, time, price);
        sessions.add(newSession);
        System.out.println("场次添加成功! 场次ID: " + sessionId);
        logger.logAction("添加场次: " + sessionId, manager.getUsername());
    }
    public void modifySession(String sessionId, Logger logger, Manager manager) {
        Optional<Session> sessionOpt = sessions.stream().filter(s -> s.getSessionId().equals(sessionId)).findFirst();

        if (sessionOpt.isPresent()) {
            Session session = sessionOpt.get();

            if (!session.getTickets().isEmpty()) {
                System.out.println("该场次已有票售出，不能修改!");
                return;
            }

            Scanner scanner = new Scanner(System.in);

            System.out.println("当前信息:");
            System.out.println(session);

            System.out.println("1. 修改影片");
            System.out.println("2. 修改时间");
            System.out.println("3. 修改价格");
            System.out.print("请选择: ");
            int choice = scanner.nextInt();
            scanner.nextLine();

            switch (choice) {
                case 1:
                    System.out.println("选择新影片:");
                    for (int i = 0; i < movies.size(); i++) {
                        System.out.printf("%d. %s%n", i + 1, movies.get(i).getTitle());
                    }
                    System.out.print("请选择: ");
                    int movieIndex = scanner.nextInt() - 1;
                    scanner.nextLine();

                    if (movieIndex < 0 || movieIndex >= movies.size()) {
                        System.out.println("无效选择!");
                        return;
                    }
                    session.setMovie(movies.get(movieIndex));
                    break;
                case 2:
                    System.out.print("输入新时间 (格式: yyyy-MM-dd HH:mm): ");
                    String timeStr = scanner.nextLine();
                    LocalDateTime time = LocalDateTime.parse(timeStr, java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));

                    if (time.isBefore(LocalDateTime.now())) {
                        System.out.println("场次时间不能在当前时间之前!");
                        return;
                    }
                    if (time.isAfter(LocalDateTime.now().plusDays(7))) {
                        System.out.println("只能安排未来一周内的场次!");
                        return;
                    }

                    session.setTime(time);
                    break;
                case 3:
                    System.out.print("输入新价格: ");
                    session.setPrice(scanner.nextFloat());
                    scanner.nextLine();
                    break;
                default:
                    System.out.println("无效选择!");
                    return;
            }

            System.out.println("场次修改成功!");
            logger.logAction("修改场次: " + sessionId, manager.getUsername());
        } else {
            System.out.println("场次不存在!");
        }
    }
    public void deleteSession(String sessionId, Logger logger, Manager manager) {
        Optional<Session> sessionOpt = sessions.stream().filter(s -> s.getSessionId().equals(sessionId)).findFirst();

        if (sessionOpt.isPresent()) {
            Session session = sessionOpt.get();

            if (!session.getTickets().isEmpty()) {
                System.out.println("该场次已有票售出，不能删除!");
                return;
            }

            sessions.remove(session);
            System.out.println("场次删除成功!");
            logger.logAction("删除场次: " + sessionId, manager.getUsername());
        } else {
            System.out.println("场次不存在!");
        }
    }

    public void listSessions() {
        System.out.println("\n===== 场次列表 =====");
        sessions.forEach(System.out::println);
    }

    public void autoSchedule(Logger logger, Manager manager) {
        if (movies.isEmpty()) {
            System.out.println("没有可排片的影片!");
            return;
        }

        LocalDate today = LocalDate.now();
        ScreeningRoom[] rooms = ScreeningRoom.values();

        int sessionCount = 0;

        for (int day = 0; day < 7; day++) {
            LocalDate date = today.plusDays(day);

            addAutoSession(date, LocalTime.of(10, 0), rooms, movies);
            sessionCount++;

            addAutoSession(date, LocalTime.of(14, 0), rooms, movies);
            sessionCount++;

            addAutoSession(date, LocalTime.of(18, 0), rooms, movies);
            sessionCount++;

            addAutoSession(date, LocalTime.of(21, 0), rooms, movies);
            sessionCount++;
        }

        System.out.println("自动排片完成! 共添加" + sessionCount + "个场次");
        logger.logAction("自动排片", manager.getUsername());
    }

    private void addAutoSession(LocalDate date, LocalTime time, ScreeningRoom[] rooms, List<Movie> movies) {
        Movie movie = movies.stream().max(Comparator.comparing(Movie::getRating)).orElse(movies.get(0));
        ScreeningRoom room = rooms[(int)(Math.random() * rooms.length)];

        String sessionId = "S" + String.format("%03d", sessions.size() + 1);

        float basePrice = 40.0f;
        if (time.getHour() >= 18) {
            basePrice *= 1.5;
        }
        basePrice *= (movie.getRating() / 8.0);

        LocalDateTime sessionTime = LocalDateTime.of(date, time);
        Session newSession = new Session(sessionId, movie, room, sessionTime, basePrice);
        sessions.add(newSession);
    }

    public void viewSessionSeats(String sessionId) {
        Optional<Session> sessionOpt = sessions.stream().filter(s -> s.getSessionId().equals(sessionId)).findFirst();

        if (sessionOpt.isPresent()) {
            Session session = sessionOpt.get();
            ScreeningRoom room = session.getRoom();
            List<Seat> seats = session.getSeats();

            System.out.println("\n===== 座位图 =====");
            System.out.println("影厅: " + room.getName());
            System.out.println("影片: " + session.getMovie().getTitle());
            System.out.println("时间: " + session.getTime());
            System.out.println("屏幕");
            System.out.println("----------------------------------");

            int index = 0;
            for (int i = 0; i < room.getRows(); i++) {
                System.out.printf("%2d ", i + 1); // 行号
                for (int j = 0; j < room.getColumns(); j++) {
                    System.out.print(seats.get(index).isAvailable() ? "O " : "X ");
                    index++;
                }
                System.out.println();
            }

            System.out.print("   ");
            for (int j = 0; j < room.getColumns(); j++) {
                System.out.printf("%2d", j + 1);
            }
            System.out.println("\n图例: O - 可用, X - 已售");
            System.out.println("总座位数: " + room.getTotalSeats() + ", 可用座位: " +
                    session.getAvailableSeats().size());
        } else {
            System.out.println("场次不存在!");
        }
    }

    public void sellTicket(Logger logger, FrontDesk frontDesk) {
        Scanner scanner = new Scanner(System.in);

        System.out.println("选择场次:");
        for (int i = 0; i < sessions.size(); i++) {
            Session session = sessions.get(i);
            System.out.printf("%d. %s - %s - %s%n", i + 1,
                    session.getSessionId(), session.getMovie().getTitle(), session.getTime());
        }
        System.out.print("请选择: ");
        int sessionIndex = scanner.nextInt() - 1;
        scanner.nextLine();

        if (sessionIndex < 0 || sessionIndex >= sessions.size()) {
            System.out.println("无效选择!");
            return;
        }
        Session session = sessions.get(sessionIndex);
        viewSessionSeats(session.getSessionId());

        System.out.print("输入要购买的座位数: ");
        int seatCount = scanner.nextInt();
        scanner.nextLine();

        List<Seat> selectedSeats = new ArrayList<>();
        for (int i = 0; i < seatCount; i++) {
            System.out.print("输入第" + (i + 1) + "个座位(格式: 行 列): ");
            int row = scanner.nextInt();
            int col = scanner.nextInt();
            scanner.nextLine();

            Optional<Seat> seatOpt = session.getSeats().stream().filter(s -> s.getRow() == row - 1 && s.getColumn() == col - 1).findFirst();

            if (seatOpt.isPresent()) {
                Seat seat = seatOpt.get();
                if (seat.isAvailable()) {
                    selectedSeats.add(seat);
                } else {
                    System.out.println("座位 " + row + "排" + col + "座 已售出!");
                    i--;
                }
            } else {
                System.out.println("无效座位!");
                i--;
            }
        }

        Ticket ticket = new Ticket(session, selectedSeats, frontDesk);

        if (session.bookSeat(selectedSeats)) {
            session.getTickets().add(ticket);
            tickets.add(ticket);

            System.out.println("\n售票成功!");
            System.out.println(ticket);
            logger.logAction("售票: " + ticket.getTicketId(), frontDesk.getUsername());
        } else {
            System.out.println("座位预订失败，请重试!");
        }
    }

    public void refundTicket(String ticketId, Logger logger, FrontDesk frontDesk) {
        Optional<Ticket> ticketOpt = tickets.stream().filter(t -> t.getTicketId().equals(ticketId)).findFirst();

        if (ticketOpt.isPresent()) {
            Ticket ticket = ticketOpt.get();

            if (ticket.isRefunfed()) {
                System.out.println("该票已退过!");
                return;
            }

            long hoursBefore = Duration.between(LocalDateTime.now(), ticket.getSession().getTime()).toHours();
            if (hoursBefore < 1) {
                System.out.println("电影开场前1小时内不能退票!");
                return;
            }

            float refundAmount = ticket.refund();
            if (refundAmount > 0) {
                System.out.printf("退票成功! 退款金额: %.2f元%n", refundAmount);
                logger.logAction("退票: " + ticketId, frontDesk.getUsername());
            } else {
                System.out.println("不符合退票条件，无法退款!");
            }
        } else {
            System.out.println("票号不存在!");
        }
    }

    public void viewDailySales() {
        LocalDate today = LocalDate.now();
        List<Ticket> dailyTickets = tickets.stream().filter(t -> t.getPurchaseTime().toLocalDate().equals(today) && !t.isRefunfed()).collect(Collectors.toList());

        printSalesReport("当日", dailyTickets);
    }
    public void viewWeeklySales() {
        LocalDate startOfWeek = LocalDate.now().with(java.time.DayOfWeek.MONDAY);
        LocalDate endOfWeek = startOfWeek.plusDays(6);

        List<Ticket> weeklyTickets = tickets.stream().filter(t -> {
                    LocalDate purchaseDate = t.getPurchaseTime().toLocalDate();
                    return !purchaseDate.isBefore(startOfWeek) &&
                            !purchaseDate.isAfter(endOfWeek) &&
                            !t.isRefunfed();
                }).collect(Collectors.toList());

        printSalesReport("当周", weeklyTickets);
    }

    public void viewMonthlySales() {
        YearMonth currentMonth = YearMonth.now();
        LocalDate startOfMonth = currentMonth.atDay(1);
        LocalDate endOfMonth = currentMonth.atEndOfMonth();

        List<Ticket> monthlyTickets = tickets.stream().filter(t -> {
                    LocalDate purchaseDate = t.getPurchaseTime().toLocalDate();
                    return !purchaseDate.isBefore(startOfMonth) &&
                            !purchaseDate.isAfter(endOfMonth) &&
                            !t.isRefunfed();
                }).collect(Collectors.toList());

        printSalesReport("当月", monthlyTickets);
    }

    private void printSalesReport(String period, List<Ticket> tickets) {
        int ticketCount = tickets.size();
        float totalRevenue = (float) tickets.stream().mapToDouble(Ticket::getTotalPrice).sum();

        long refundCount = this.tickets.stream().filter(Ticket::isRefunfed).count();

        float refundAmount = (float) this.tickets.stream().filter(Ticket::isRefunfed).mapToDouble(t -> t.getTotalPrice() - t.refund()).sum();

        System.out.println("\n===== " + period + "销售报告 =====");
        System.out.println("销售票数: " + ticketCount);
        System.out.printf("销售总额: %.2f元%n", totalRevenue);
        System.out.println("退票数量: " + refundCount);
        System.out.printf("退票金额: %.2f元%n", refundAmount);
        System.out.printf("实际收入: %.2f元%n", totalRevenue - refundAmount);
    }
    public void resetFrontDeskPassword(String username, Logger logger, Manager manager) {
        Optional<User> userOpt = users.stream().filter(u -> u.getUsername().equals(username) && u.getUserType().equals("前台")).findFirst();

        if (userOpt.isPresent()) {
            User user = userOpt.get();
            user.setPassword("123456");
            System.out.println("密码已重置为123456");
            logger.logAction("重置前台密码: " + username, manager.getUsername());
        } else {
            System.out.println("前台用户不存在！");
        }
    }
}